package com.lib.online.model;

import java.io.Serializable;
import java.sql.Blob;
import java.util.Date;
import java.util.ArrayList;
import java.util.List;

import org.codehaus.jackson.annotate.JsonIgnore;
import org.hibernate.annotations.Fetch;
import org.hibernate.annotations.FetchMode;
import org.joda.time.DateTime;
import org.springframework.format.annotation.DateTimeFormat;

import javax.persistence.*;
import javax.xml.bind.annotation.*;

/**
 * @author ievgen_s
 */

@XmlRootElement(name = "reading")
@XmlType(propOrder = {"book_id",	
	"title", 
	"genre", 
	"pages", 
	"pubDate", 
	"author",	
	"isbn" })
@Entity
@Table(name="readings")
@Cacheable
public class Reading implements Serializable, Comparable<Reading> {
    
	
    private static final long serialVersionUID = -1688933328974405204L;
    private Integer book_id;
    private String title; 
    private List<Genre> genre;
    private Integer pages;
    private DateTime pubDate;    
    private Author author;
    @XmlTransient
    @JsonIgnore
    private List<User> readers;
    private String isbn;
    
    @XmlTransient
    @JsonIgnore
    private Blob data;
    @XmlTransient
    @JsonIgnore
    private String content_type;

    // TODO:type

    public Reading() {
	this.pubDate = new DateTime();	
    }
    
    public Reading(Integer bookId, String title, Integer pages, Date pubDate,
	    String isbn) {
        this.book_id=bookId;
	this.title = title;
	this.genre = new ArrayList<Genre>();	
	this.pages = pages;
	this.pubDate = new DateTime(pubDate);	
	this.readers = new ArrayList<User>();
	this.isbn = isbn;

    }

   
    
    @Id 
	@Column(name="book_id")
    @GeneratedValue  
    public Integer getBook_id() {
	return book_id;
    }

    public void setBook_id(Integer bookId) {
	this.book_id = bookId;
    }

    @Column(name="title")
    public String getTitle() {
	return this.title;
    }

    public void setTitle(String title) {
	this.title = title;
    }

    @ManyToMany(
            cascade = {CascadeType.PERSIST, CascadeType.MERGE},
            mappedBy = "books",            
            fetch=FetchType.EAGER
            )
    @Fetch(value = FetchMode.SUBSELECT)    
    public List<Genre> getGenre() {
	return this.genre;
    }

    public void setGenre(List<Genre> genre) {
	this.genre=genre;
    }

    @Column(name="pages")
    public Integer getPages() {
	return this.pages;
    }

    public void setPages(Integer pages) {
	this.pages = pages;
    }

    @Temporal(TemporalType.DATE)
    @Column(name="pub_date")
    @DateTimeFormat(pattern="yyyy/MM/dd")
    public Date getPubDate() {
	return this.pubDate.toDate();
    }

    public void setPubDate(Date pubDate) {
	this.pubDate = new DateTime(pubDate);
    }

    @ManyToOne
    @JoinColumn(name="author_id_fk")
    public Author getAuthor() {
		return author;
	}

	public void setAuthor(Author author) {
		this.author = author;
	}

	 
    

    @ManyToMany(
            cascade = {CascadeType.PERSIST, CascadeType.MERGE},
            mappedBy = "books",
            targetEntity = com.lib.online.model.User.class,
            fetch=FetchType.EAGER
            )
	 @Fetch(value = FetchMode.SUBSELECT)
    @XmlTransient
    @JsonIgnore   
    public List<User> getReaders() {
	return this.readers;
    }

    public void setReaders(List<User> readers) {
	this.readers= readers;
    }
  

    public void removeReader(User user) {
	this.readers.remove(user);
    }

    @Column(name="isbn")
    public String getIsbn() {
	return isbn;
    }

    public void setIsbn(String isbn) {
	this.isbn = isbn;
    }

    
   
    @Column(name="data")   
    @Lob
    @XmlTransient
    @JsonIgnore
    public Blob getData() {
        return data;
    }

    public void setData(Blob data) {
        this.data = data;
    }

    @Column(name="content_type")   
    @XmlTransient
    @JsonIgnore
    public String getContent_type() {
        return content_type;
    }

    public void setContent_type(String content_type) {
        this.content_type = content_type;
    }

    @Override
    public int compareTo(Reading r) {
	return title.compareTo(r.getTitle());

    }

    @Override
    public String toString() {
	return this.title;
    }

}